<?php

/**
 * Gère le cache
 *
 * @package cass
 * @author Mickaël CASTANHEIRO <mickael.castanheiro@gmail.com>
 * @version 1.0
 */

namespace cass;

class Cache extends Element {
    const NO = 0; // Pas de cache
    const SESSION_NO = 1; // Pas de cache pour les gens connectés
    const SESSION_ONCE = 2; // Cache identique pour les gens connectés et non connectés
    const SESSION_TWICE = 3; // Cache identique pour les gens connectés et un autre pour les gens non connectés
    const SESSION_MULTIPLE = 4; // Cache différent pour chaque personne connectée

    protected $type;
    protected $uri;
    protected $parameters;

    /**
     * Constructeur du cache
     */
    public function __construct() {
	$this->type = self::NO;
        $this->parameters = new Parameters;
	$this->uri = new Uri;
    }

    /**
     * Indique si le cache est activé dans la situation actuelle et pour le type
     * indiqué plus tôt
     */
    public function isEnabled() {
	$session = Session::getInstance();
	switch ($this->type) {
	    case self::NO:
		return false;
		break;

	    case self::SESSION_NO:
		return (!$session->isAuthenticated()); // Si pas connecté, il y a un cache, sinon pas de cache
		break;

	    case self::SESSION_ONCE:
	    case self::SESSION_TWICE:
	    case self::SESSION_MULTIPLE:
		return true; // Cache activé dans ces cas là
		break;
	}
    }

    protected function getSessionName() {
	switch ( $this->type ) {
	    case self::SESSION_NO:
	    case self::SESSION_ONCE:
		return 'nosession';
		break;

	    case self::SESSION_TWICE:
		return (Session::getInstance()->isAuthenticated()) ? 'session' : 'nosession';
		break;

	    case self::SESSION_MULTIPLE:
		return (Session::getInstance()->isAuthenticated()) ? 'session'.Session::getInstance()->getUser()->getId() : 'nosession';
                break;
	}
    }

    protected function getFileName() {
	$session = $this->getSessionName();        
	$package = formatSeparatorToUpper($this->uri->package, '-', false);
	$action = $this->uri->action;
	$request = formatSeparatorToUpper($this->uri->request, '-', true);
	$parameters = '';
	if (!empty($this->uri->parameters))
	    $parameters = ',' . implode(',', $this->uri->parameters);

	return __PATH__ . Data::directories('cache') . $package . '/' . $action.$request.$parameters . '.' . $session  .  Data::extensions('cache');
    }

    public function getRender() {
	if (!$this->isEnabled()) {
	    return false;
	}
	
	$cache = $this->getFileName();
	if (!file_exists($cache)) {
	    return false;
	}
	else {
	    $xml = \DomDocument::load($cache);
            $title = $xml->getElementsByTagName('title')->item(0)->nodeValue;
            $ariane = unserialize($xml->getElementsByTagName('ariane')->item(0)->nodeValue);
            $css = unserialize($xml->getElementsByTagName('css')->item(0)->nodeValue);
            $js = unserialize($xml->getElementsByTagName('js')->item(0)->nodeValue);
            $content = urldecode($xml->getElementsByTagName('content')->item(0)->nodeValue);
         
	    $this->parameters->setTitle($title);
	    $this->parameters->setAriane($ariane);
	    $this->parameters->setCss($css);
	    $this->parameters->setJs($js);
	    return $content;
	}	
    }

    public function setRender($_render) { 
	$xml = new \DOMDocument; 
        $root = $xml->appendChild($xml->createElement('root'));
        $title = $root->appendChild($xml->createElement('title', $this->parameters->getTitle()));
        $ariane = $root->appendChild($xml->createElement('ariane', serialize($this->parameters->getAriane())));
        $css = $root->appendChild($xml->createElement('css', serialize($this->parameters->getCss())));
        $js = $root->appendChild($xml->createElement('js', serialize($this->parameters->getJs())));
        $content = $root->appendChild($xml->createElement('content', urlencode($_render)));

        $xml = $xml->saveXML();
       
        // Enregistrement
        $dir = __PATH__ . Data::directories('cache') . $this->uri->package;
        if ( !is_dir($dir) ) {
            mkdir($dir);
        }
        file_put_contents($this->getFileName(), $xml);
    }

}